This chapter details the routines and processes in Tools Plus that consume memory. All Tools Plus objects exist in your application’s heap (the memory you allocate to an application in the “Get Info” dialog under MultiFinder or System 7). The only exception to this is a global record that is used by Tools Plus to keep its internal workings functioning. The Tools Plus global record is placed on your application’s stack. Fortunately, the global record is less than 2K, so it consumes relatively little stack space.
Almost all the objects created by Tools Plus routines are relocatable, and are therefore accessed internally by handles. The use of relocatable objects insures that the largest contiguous memory block can be allocated when required. The only non-relocatable objects created by Tools Plus are window records, but this is not a problem providing your application calls InitToolsPlus early in the program. This allocates the window records low in memory where they won’t cause any heap fragmentation.
Each routine consumes stack memory just to execute its own code. After the routine has completed execution, that memory is automatically reclaimed by the Memory Manager as it is needed. The objects created by these routines (such as buttons, list boxes, etc.) remain in memory (the application heap) until they are explicitly deleted by a specific routine, or when your application ends. Routines that consume memory only during their execution are not listed.
It is your responsibility to ensure that an operation can be completed with the amount of memory that is available to your application. For example, testing can determine the exact amount to memory required to open a window with 5 buttons, two list boxes, and 40 editing fields. Your application should ensure that the memory required to create such a window can be allocated safely before the WindowOpen statement is executed.
Measurements
````````````
Measurements of memory consumption are approximate for two very important reasons. Firstly, many objects contain handles to other objects, and because of this, they consume memory from handle blocks. Handle blocks are a pool of handles that are available to any process or object that requires them. When a process or object no longer requires a handle, the handle is released back into the available pool. Additional memory will not be required providing that the demand for handles never exceeds the available supply. As soon as the demand for handles exceeds the available supply, an additional block of 64 handles is automatically created, consuming 512 bytes of memory. An entire block will be created even if only one more handle is needed.
The second reason approximate values are provided instead of exact values, is because the Macintosh’s various managers are not always consistent in the way they allocate memory. The List Manager, for example, needs over 5K the first time any of its routines are accessed. Once that 6K kernel is loaded, memory consumption is nominal. Also, the memory consumed by various processes will likely vary between versions of the System.
Routines that consume heap space (by category)
``````````````````````````````````````````````
The following routines create objects in memory, thereby consuming heap space:
Program Initialization: InitToolsPlus
Windows: WindowOpen
WindowTitle
Buttons: NewButton
ButtonTitle
Scroll Bars: NewScrollBar
Editing Field: NewField
ActivateField (if a field is not already
active)
ClickInField (if a field is not already
active)
List Boxes: NewListBox
SetListBoxText
InsertListBoxLine
Menus: AppleMenu
Menu
InsertMenuItem
RenameItem
Cursors: CursorShape
ResetCursor
NewCursorTable
CursorZone
Color Drawing/
Multiple Screens: NumberOfScreens
BeginUpdateScreen
DrawIcon
Routines that consume heap space (alphabetic)
`````````````````````````````````````````````
The following section alphabetically lists routines that create objects in memory. You will likely notice that in most cases, the amount of memory consumed is negligible.
ActivateField When an editing field is activated, it consumes 8
bytes of memory, plus 1 byte for each character of
edited text. When the editing field is deactivated,
either by deactivating it, activating another field,
clicking in another field, or closing the window, this
memory is released.
AppleMenu The Apple menu requires about 4K bytes of memory.
BeginUpdateScreen BeginUpdateScreen allocated about 40 bytes. This
memory is deallocated when EndUpdateScreen is called.
ButtonTitle Each character of the button’s title string consumes 1
byte of memory. Memory consumed by any previous title
is released. Deleting the button, or closing its
window releases its memory.
ClickInField When an editing field is activated by ClickInField, it
consumes an additional 8 bytes of memory, plus 1 byte
for each character of edited text. When the editing
field is deactivated, either by deactivating it,
activating another field, clicking in another field,
or closing the window, this memory is released.
CursorShape When a cursor is displayed the first time, the CURS
resource is loaded into memory consuming 16 bytes of
memory. If your application has an animated cursor,
the acur resource is also loaded, consuming 4 bytes
plus an additional 4 bytes per animation frame.
If a resource is flagged as “purgeable” it is
automatically unloaded to reclaim memory when needed.
CursorZone Each cursor zone requires about 28 bytes of memory.
Deleting a cursor zone releases its memory.
DrawIcon When an icon is displayed the first time, the required
resource (cicn, icl8, icl4, ICN#, or ICON) is loaded
into memory. Depending on your icon family, this may
consume as much as 2K of memory.
If a resource is flagged as “purgeable” it is
automatically unloaded to reclaim memory when needed.
InitToolsPlus Multiply the value of MaxWindows by 300 bytes to
determine the amount of memory consumed by windows.
This amount is fixed, regardless if those windows are
ever opened by your application. About 40k is
consumed by loading the code segments that contain
Tools Plus’s libraries.
InsertListBoxLine Each line in a list box requires about 4 bytes of
memory, plus 1 byte per character of text displayed in
the line. Deleting the line in the list box, deleting
its containing list box, or closing its window
releases the memory used by the line.
InsertMenuItem Each menu item requires about 10 bytes of memory plus
the length of the item’s title. Deleting an item
releases its memory.
Menu Each menu requires about 36 bytes of memory. Each
menu item requires an additional 10 bytes plus the
length of the item’s title. Deleting the menu
releases its memory and that of its associated items.
Deleting an item releases its memory.
NewButton Each button requires about 50 bytes of memory, plus
the length of the button’s title. Deleting the
button, or closing its window releases its memory.
NewCursorTable Each cursor table requires about 20 bytes of memory.
Deleting a cursor table releases its memory and that
of its associated zones.
NewField Each editing field requires about 52 bytes of memory,
regardless of the number of characters used by the
field’s string. Deleting the editing field, or
closing its window releases its memory.
NewListBox Each list box requires about 300 bytes of memory. The
first list box created will consume an additional 6K
which is required to load the List Manager. Deleting
the list box, or closing its window releases its
memory and the memory used by its associated lines.
NewScrollBar Each scroll bar requires about 70 bytes of memory.
Deleting the scroll bar, or closing its window
releases its memory.
NumberOfScreens The amount of memory consumed by NumberOfScreens
depends on the number of monitors present when your
application runs, and their settings. In the worst
case, about 40 bytes are consumed per monitor.
Note that the amount of memory consumed is not
incremented each time NumberOfScreens is called.
RenameItem When a menu item is renamed, it consumes 1 byte plus
the length of the item’s title. The memory consumed
by the previous name is released. Deleting the menu
releases its memory and that of its associated items.
Deleting an item releases its memory.
ResetCursor When a cursor is displayed the first time, the CURS
resource is loaded into memory consuming 16 bytes of
memory. If a resource is flagged as “purgeable” it is
automatically unloaded to reclaim memory when needed.
SetListBoxText Each line in a list box requires about 4 bytes of
memory, plus 1 byte per character of text displayed in
the line. Deleting the line in the list box, deleting
its containing list box, or closing its window
releases the memory used by the line.
WindowOpen Each open window consumes an additional 300 bytes.
Closing the window releases the memory.
WindowTitle Each character of the window’s title string consumes 1
byte of memory. Memory consumed by any previous title
is released. Closing the window releases title
memory.
Good memory habits
``````````````````
It’s a very good idea to check the amount of available contiguous memory before allocating objects or calling a routine that may need to be loaded from disk (ie: a segment that is not yet in memory). Do the same when you open a document too, because there are a number of applications out there that bomb just because a user created a document on a 8-meg Mac and tried to open it on another Mac with less memory. Users perceive this type of behavior as being indicative of an unreliable program (it keeps bombing on me for no reason).